package com.stdz.counter.controller;


import cn.hutool.core.date.DateUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.stdz.counter.constant.MeterConstant;
import com.stdz.counter.core.cache.MeterFlagCache;
import com.stdz.counter.core.cache.MeterInfoCache;
import com.stdz.counter.core.cache.MeterInfoTempCache;
import com.stdz.counter.core.config.SwitchConfig;
import com.stdz.counter.core.constant.ClearMode;
import com.stdz.counter.core.exception.ResultException;
import com.stdz.counter.core.pool.SyncThreadPool;
import com.stdz.counter.dao.MeterHDao;
import com.stdz.counter.dao.MeterInfoDao;
import com.stdz.counter.dao.ModbusComDao;
import com.stdz.counter.entity.*;
import com.stdz.counter.service.DeviceService;
import com.stdz.counter.service.MeterService;
import com.stdz.counter.service.MeterTaskService;
import com.stdz.counter.service.ReportService;
import com.stdz.counter.utils.MeterClearHelper;
import com.stdz.counter.utils.MeterHelper;
import com.stdz.counter.utils.ModbusHelper;
import com.stdz.counter.utils.excel.ExcelExportUtils;
import com.sun.corba.se.impl.orbutil.concurrent.Sync;
import de.re.easymodbus.exceptions.ModbusException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author peanut
 */
@Controller
@RequestMapping("/device")
public class DeviceController {

    private static final Logger LOG = LoggerFactory.getLogger(DeviceController.class);

    @Autowired
    DeviceService deviceService;

    @Autowired
    MeterService meterService;

    @Autowired
    MeterTaskService meterTaskService;
    @Autowired
    private MeterInfoDao meterInfoDao;
    @Autowired
    private ModbusComDao modbusComDao;
    @Autowired
    private ReportService newReportService;
    @Autowired
    private MeterHDao meterHDao;

    @ResponseBody
    @RequestMapping("/addDevices")
    public Map<String, Object> addDevices(@RequestBody Map map){
        Map<String, Object> result = new HashMap<>();
        Boolean isSuccess = false;
        try {
            MeterInfo meterInfo = MeterHelper.createMeterInfo(map);
            if (!SwitchConfig.METER_TEST_CLOSE) {
                ModbusHelper.initMeterInfo(meterInfo, map);
            }
            meterInfoDao.injectMeterInfo(meterInfo);
            this.refreshMeterInfoCache(meterInfo.getComPort());
            isSuccess = true;
        } catch (ResultException e) {
            e.printLog();
            result.put("message", e.getMsg());
        } catch (Exception e) {
            LOG.error("add device exception:", e);
            result.put("message", "服务端异常:" + e.getClass().getName());
        }
        result.put("code", isSuccess);
        return result;
    }


    @ResponseBody
    @RequestMapping("/restartSerialPort")
    public Map<String, Object> restartSerialPort(@RequestBody Map map){

        Map<String, Object> result = new HashMap<>();

        Boolean isSuccess = false;
        try {
//            isSuccess = deviceService.restartSerialPort(map.get("serialPort").toString());
            String comPort = map.get("serialPort").toString();
            List<MeterInfo> meterInfos = meterInfoDao.queryMeterInfosByCom(comPort);
            if (meterInfos != null && meterInfos.size() > 0) {
                SyncThreadPool.submit(comPort, meterInfos);
                isSuccess = true;
                result.put("message", "重启成功");
            } else {
                result.put("message", "未找到相关设备");
            }


        }catch (Exception e) {
            result.put("message", "服务端异常");
        }
        result.put("code", isSuccess);
        return result;
    }


    @ResponseBody
    @RequestMapping("/allCounter")
    public Map<String, Object> allCounter(@RequestBody Map map){
        PageHelper.startPage(map.containsKey("pageNum") ? Integer.valueOf(map.get("pageNum").toString()).intValue() : MeterConstant.UPPER_ROW_INDEX,
                map.containsKey("pageNum") ? Integer.valueOf(map.get("pageSize").toString()).intValue() : 12);
        Map<String, Object> result = new HashMap<>();
        Boolean isSuccess = false;
        try {
//            List<Meter> list = deviceService.findAll();
//            for (Meter meter : list) {
//                if ((StringUtils.isNotBlank(meter.getAl1()) || StringUtils.isNotBlank(meter.getAl2())
//                        || StringUtils.isNotBlank(meter.getLowerRow()) || StringUtils.isNotBlank(meter.getUpperRow())) &&
//                        (!("0").equals(meter.getAl1()) || !("0").equals(meter.getAl2())
//                                || !("0").equals(meter.getLowerRow()) || !("0").equals(meter.getUpperRow()))) {
//                    // 去修改数据库  在线状态
//                    meterService.updateValues(meter.getId(), meter.getUpperRow(), meter.getLowerRow(),meter.getAl1(), meter.getAl2(), meter.getScal(), "0" );
//                } else {
//                    meterService.updateValues(meter.getId(), meter.getUpperRow(), meter.getLowerRow(),meter.getAl1(), meter.getAl2(), meter.getScal(), "1" );
//                }
//            }
//            Page<Meter> meters = deviceService.findAllCounters();
            Page<MeterInfo> meters = meterInfoDao.queryAll();
            isSuccess = true;
            result.put("message", "获取成功");
            result.put("data", meters.getResult());
            result.put("count", meters.size());
            Integer onLineCount = meterInfoDao.findByOnline();
            result.put("onLineCount", onLineCount);
        }catch (Exception e) {
            result.put("message", "服务端异常");
        }
        result.put("code", isSuccess);
        return result;
    }

    @ResponseBody
    @RequestMapping("/findAlls")
    public Map<String, Object> findAlls(){
        Map<String, Object> result = new HashMap<>();
        Boolean isSuccess = false;
        try {
            List<MeterInfo> meters = meterInfoDao.queryAllMeterInfos();
            isSuccess = true;
            result.put("data", meters);
            result.put("message", "获取成功");
        }catch (Exception e) {
            result.put("message", "服务端异常");
        }
        result.put("code", isSuccess);
        return result;
    }


    @ResponseBody
    @RequestMapping("/findAllPorts")
    public Map<String, Object> findAllPorts(){
        Map<String, Object> result = new HashMap<>();
        Boolean isSuccess = false;
        List<String> ports = new ArrayList<>();
        try {
//            ports = deviceService.findAllPorts();
            ports = meterInfoDao.queryAllComPorts();
            isSuccess = true;
            result.put("message", "获取成功");
            result.put("data",ports);
        }catch (Exception e) {
            result.put("message", "服务端异常");
        }
        result.put("code", isSuccess);
        return result;
    }


    @ResponseBody
    @RequestMapping("/suspend")
    public Map<String, Object> suspend(@RequestBody Map map){
        Map<String, Object> result = new HashMap<>();
        Boolean isSuccess = false;
        try {
            if (map.containsKey("id") && map.containsKey("suspendFlag")) {
                int meterId = Integer.parseInt(map.get("id").toString());
                int suspendFlag = Integer.parseInt(map.get("suspendFlag").toString());
//                Map meterMap =  deviceService.findById(Long.valueOf(map.get("id").toString()));
                MeterInfo meterInfo = meterInfoDao.queryMeterInfo(meterId);
                int operate = 0;
                String operateName = "";
                int nextSuspendFlag = 0;
                if (suspendFlag == 0) { // 当前非暂停状态
                    operateName = "暂停";
                    operate = ModbusHelper.setPause(meterInfo.getComPort());
                    nextSuspendFlag = 1;
                } else {
                    operateName = "恢复";
                    operate = ModbusHelper.setContinue(meterInfo.getComPort());
                    nextSuspendFlag = 0;
                }
                if (operate == 1) {
                    meterInfoDao.updateSuspendFlag(meterId, nextSuspendFlag);
                    isSuccess = true;
                    result.put("message", operateName + "成功");
                } else {
                    result.put("message", operateName + "失败");
                }
            } else {
                result.put("message", "获取设备信息异常");
            }

        }catch (Exception e) {
            result.put("message", "服务端异常, 请检查是否正常连接");
        }
        result.put("code", isSuccess);
        return result;
    }

    @ResponseBody
    @RequestMapping("/clear")
    public Map<String, Object> clear(@RequestBody Map map){
        Map<String, Object> result = new HashMap<>();
        Boolean isSuccess = false;
        try {
            if (map.containsKey("id")) {
                int meterId = Integer.parseInt(map.get("id").toString());
                MeterInfo meterInfo = meterInfoDao.queryMeterInfo(meterId);
                if (meterInfo == null) {
                    result.put("message", "未找到设备信息");
                } else {
                    int operate = 0;
                    if (meterInfo.getClearMode() == ClearMode.SINGLE_CLEAR.getMode()) {
                        operate = ModbusHelper.singleClear1(meterInfo.getComPort());
                    } else if (meterInfo.getClearMode() == ClearMode.BOTH_CLEAR.getMode()) {
                        operate = ModbusHelper.bothClear(meterInfo.getComPort());
                    } else {
                        result.put("message", "暂未开启清零方式");
                    }
                    if (operate == 1) {
                        isSuccess = true;
                        List<MeterInfo> syncMeter = new ArrayList<>();
                        syncMeter.add(meterInfo);
                        SyncThreadPool.submit(meterInfo.getComPort(), syncMeter);

                        result.put("message", "清零成功");
                    } else {
                        result.put("message", "清零失败");
                    }
                }
            }

        }catch (Exception e) {
            result.put("message", "服务端异常");
        }
        result.put("code", isSuccess);
        return result;
    }


    @ResponseBody
    @RequestMapping("/delete")
    public Map<String, Object> delete(@RequestBody Map map){
        Map<String, Object> result = new HashMap<>();
        Boolean isSuccess = false;
        List<String> ports = new ArrayList<>();
        try {
            if (map.containsKey("id") && map.containsKey("comPort")) {
                int meterId = Integer.parseInt(map.get("id").toString());
                String comPort = map.get("comPort").toString();
                meterInfoDao.delMeterInfo(meterId);
                this.refreshMeterInfoCache(comPort);
//                deviceService.delete(Long.valueOf(map.get("id").toString()));
                isSuccess = true;
                result.put("message", "删除成功");
            }
        }catch (Exception e) {
            result.put("message", "服务端异常");
        }
        result.put("code", isSuccess);
        return result;
    }


    @ResponseBody
    @RequestMapping("/meterDetails")
    public Map<String, Object> meterDetails(@RequestBody Map map){
        Map<String, Object> result = new HashMap<>();
        Boolean isSuccess = false;
        try {
            if (map.containsKey("id")) {
                int meterId = Integer.parseInt(map.get("id").toString());
                MeterInfo meterInfo = meterInfoDao.queryMeterInfo(meterId);
                if (meterInfo == null) {

                }
//                Map<String, Object> data = deviceService.findById(id);
//                if (data != null) {
//                    MeterTask meterTask = meterTaskService.findByMeterId(Integer.parseInt(String.valueOf(id)));
//                    if (meterTask != null) {
//                        data.put("isOpen", true);
//                    }
//                }
                isSuccess = true;
                result.put("message", "获取成功");
                result.put("data", meterInfo);
            }
        }catch (Exception e) {
            result.put("message", "服务端异常");
        }
        result.put("code", isSuccess);
        return result;
    }

    @ResponseBody
    @RequestMapping("/setCounterIndex")
    public Map<String, Object> setCounterIndex(@RequestBody Map map) {
        Map<String, Object> result = new HashMap<>();
        Boolean isSuccess = false;
        try {
            if (map.containsKey("id")) {
                int meterId = Integer.parseInt(map.get("id").toString());
                MeterInfoTempCache.getInstance().clearMeterInfo(meterId);
                MeterInfo meterInfo = meterInfoDao.queryMeterInfo(meterId);
                this.refreshMeterInfoCache(meterInfo.getComPort());
                if (MeterFlagCache.isMeterOnline(meterId)) {
                    isSuccess = true;
                }
                result.put("message", "获取成功");
            }
        }catch (Exception e) {
            result.put("message", "服务端异常");
        }

        result.put("code", isSuccess);
        return result;
    }

    @ResponseBody
    @RequestMapping("/setCounter")
    public Map<String, Object> setCounter(@RequestBody Map map){
        Map<String, Object> result = new HashMap<>();
        Boolean isSuccess = false;
        try {
            int meterId = Integer.parseInt(map.get("meterId").toString());
            MeterInfo oridinalMeter = meterInfoDao.queryMeterInfo(meterId);
            MeterInfo meterInfo = MeterHelper.modMeterInfo(map, oridinalMeter.getDecimalDigit());
            if (!SwitchConfig.METER_TEST_CLOSE) {
                ModbusHelper.initMeterInfo(meterInfo, map);
            }
            meterInfoDao.updateMeterInfo(meterInfo);
            this.refreshMeterInfoCache(meterInfo.getComPort());
            isSuccess = true;
        } catch (ResultException e) {
            result.put("message", e.getMsg());
        } catch (Exception e) {
            LOG.error("set counter exception:", e);
            result.put("message", "服务端异常");
        }
        result.put("code", isSuccess);
        return result;
    }



    @ResponseBody
    @RequestMapping("/allComs")
    public Map<String, Object> allComs(){
        Map<String, Object> result = new HashMap<>();
        Boolean isSuccess = false;
        try {
            List<String> coms = deviceService.findAllComs();
            isSuccess = true;
            result.put("data", coms);
            result.put("message", "设置成功");
        }catch (Exception e) {
            result.put("message", "服务端异常");
        }
        result.put("code", isSuccess);
        return result;
    }


    @ResponseBody
    @RequestMapping("/findAllModbusType")
    public Map<String, Object> findAllModbusType(){
        Map<String, Object> result = new HashMap<>();
        boolean isSuccess = false;
        try {
            List<ModbusCom> modbusTypes = modbusComDao.getAllComPorts();
            isSuccess = true;
            result.put("data", modbusTypes);
            result.put("message", "设置成功");
        }catch (Exception e) {
            LOG.error("当前的异常是：" + e.getMessage());
            result.put("message", "服务端异常");
        }
        result.put("code", isSuccess);
        return result;
    }



    @ResponseBody
    @RequestMapping("/getSerialPortMeter")
    public Map<String, Object> getSerialPortMeter(@RequestBody Map map){
        Map<String, Object> result = new HashMap<>();
        Boolean isSuccess = false;
        try {
            Integer count = meterService.findByCom(map);
            isSuccess = true;
            result.put("data", count);
            result.put("message", "设置成功");
        }catch (Exception e) {
            LOG.error("当前的异常是：" + e.getMessage());
            result.put("message", "服务端异常");
        }
        result.put("code", isSuccess);
        return result;
    }


    /**
     * 折线图
     * @param map
     * @return
     */
    @ResponseBody
    @RequestMapping("/curveStatistics")
    public Map<String, Object> curveStatistics(@RequestBody Map map){
        Map<String, Object> result = new HashMap<>();
        Boolean isSuccess = false;
        try {
            // 处理时间
            String type = map.get("type").toString();
            String date = map.get("date").toString();
            String meterIds = map.get("meterIds").toString();
            List<CurveData> dataMap = newReportService.findByDate(type, date, meterIds);
            isSuccess = true;
            result.put("data", dataMap);
            if (dataMap != null && dataMap.size() > 0) {
                result.put("timeData", dataMap.get(0).getDateData());
            }
            result.put("message", "设置成功");
        }catch (Exception e) {
            LOG.error("当前的异常是：" + e.getMessage());
            result.put("message", "服务端异常");
        }
        result.put("code", isSuccess);
        return result;
    }
    @ResponseBody
    @RequestMapping("/exportCurve")
    public Map<String, Object> exportCurve(@RequestBody Map map, HttpServletRequest request){
        Map<String, Object> result = new HashMap<>();
        try {
            // 处理时间
            String type = map.get("type").toString();
            String dateParam = map.get("date").toString();
            String meterIds = map.get("meterIds").toString();
            Date date = DateUtil.parse(dateParam);
            // List<CurveData> dataMap = deviceService.findByDate(type, date, meterIds);
            String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date.getTime());
            String laterDateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date.getTime() + 1000 * 60 * 60 * 24);
            List<ExcelTemplate> lists = meterHDao.exportHourDataByDate(dateStr, meterIds);
            // 将list分组
            Map<String, List<ExcelTemplate>> groupLists = deviceService.groupLists(lists);

            ExcelExportUtils.exportExcel("计数器上排值折线统计报表", groupLists,dateParam, request);

            result.put("code", true);
            result.put("message", "请稍后到C盘的counter文件夹下查看");
        }catch (Exception e) {
            LOG.error("当前的异常是：" + e.getMessage());
            result.put("code", false);
            result.put("message", "导出文档失败");
        }
        return result;
    }

    /**
     * 柱状图
     * @param map
     * @return
     */
    @ResponseBody
    @RequestMapping("/columnChart")
    public Map<String, Object> columnChart(@RequestBody Map map){
        Map<String, Object> result = new HashMap<>();
        Boolean isSuccess = false;
        try {
            // 处理时间
            String type = map.get("type").toString();
            String date = map.get("date").toString();
            String meterIds = map.get("meterIds").toString();
            List<ColumnarData> dataMap = newReportService.findColumnChartByDate(type, date, meterIds);
            isSuccess = true;
            result.put("data", dataMap);
            result.put("message", "设置成功");
        }catch (Exception e) {
            LOG.error("当前的异常是：" + e.getMessage());
            result.put("message", "服务端异常");
        }
        result.put("code", isSuccess);
        return result;
    }

    private void refreshMeterInfoCache(String comPort) {
        List<MeterInfo> newMeterInfos = meterInfoDao.queryAllMeterInfos();

        List<MeterInfo> meterInfos = meterInfoDao.queryMeterInfosByCom(comPort);
        MeterInfoCache.getInstance().cacheComMeterInfos(comPort, meterInfos);
        SyncThreadPool.submit(comPort, meterInfos);
        MeterClearHelper.getInstance().checkClearTask(comPort);
    }
}
